`timescale 1ns / 1ps
//Name: Robert Smith
//PID: A08609119
//Name: Shreenidhi Chowkwale
//PID: A09089080

// I_WIDTH  : instruction width
// IA_WIDTH : instruction address width
// D_WIDTH  : data width
// PA_WIDTH : port address width
 
module backend#(parameter I_WIDTH = 17, IA_WIDTH = 10, REG_SIZE = 4, D_WIDTH = 34, PA_WIDTH = 4, DA_WIDTH = 13, FIFO_WIDTH = 68, LDINST_WIDTH = 136, OPCODE_WIDTH =  5)
(
    input  clk,
    input  reset_i,
    
    // inputs from the fetch unit
    input  [I_WIDTH-1 : 0]  instruction_data_i,
	 input  [IA_WIDTH-1 : 0]  instruction_label_i,
	 input  [D_WIDTH-1 : 0] instruction_imm_i,
    input  [IA_WIDTH-1 : 0] instruction_addr_i,
    input  instruction_valid_i,    
    input  [FIFO_WIDTH-1 : 0]  load_data_i,
    input  load_data_valid_i,
    
    // outputs to the fetch unit
    output dequeue_o,
    output restart_o,
    output [IA_WIDTH-1 : 0] restart_addr_o,
    output load_store_valid_o,
    output store_en_o,
    output [IA_WIDTH-1 : 0] load_store_addr_o,
    output [I_WIDTH-1 : 0]  store_data_o,
    
    // I/O interface
    output in_req_o,
    output out_req_o,
    output [PA_WIDTH-1 : 0] in_addr_o,
    output [PA_WIDTH-1 : 0] out_addr_o,
    input  [D_WIDTH-1 : 0]  in_data_i,
    output [D_WIDTH-1 : 0]  out_data_o,
    input  in_ack_i,
    input  out_ack_i,
	 
	 //Timing test outputs
	 output [D_WIDTH - 1 : 0] rd0_o,
	 output [D_WIDTH - 1 : 0] rd1_o,
	 output [D_WIDTH - 1 : 0] wd_o
);

	//Not used so assign to 0.
	assign load_store_valid_o = 1'b0;
	assign store_en_o = 1'b0;
	assign load_store_addr_o = 10'b0;
	assign store_data_o = 17'b0;
	
	//Control Signals
	wire is_jal, is_dmem, is_alu;
	wire [OPCODE_WIDTH - 1 : 0] op_code;
	wire [REG_SIZE - 1 : 0] wa, ra0, ra1;
	wire wen, ldinst_valid, is_computation_imm, is_sw, is_staj_or_ldrsw, is_in;
	
	wire is_swtch, has_lab_or_imm, uses_label, is_swtch_or_jr, is_staj, is_infloop;
	
	wire read_write_req, write_en;
	
	wire is_gic;
	
	wire refused;
	wire branch;
	
	wire [32 - 1 : 0] instr_count;

	control control_module
	(
		.clk(clk)
		,.reset_i(reset_i)
		,.instruction_data_i(instruction_data_i)
		,.instruction_valid_i(instruction_valid_i)
		,.refused_i(refused)
		,.branch_i(branch)
      ,.is_jal_o(is_jal)
		,.is_dmem_o(is_dmem)
		,.is_alu_o(is_alu)
		,.wen_o(wen)
		,.ldinst_valid_o(ldinst_valid)
		,.is_computation_imm_o(is_computation_imm)
		,.op_code_o(op_code)
		,.wa_o(wa)
		,.ra0_o(ra0)
		,.ra1_o(ra1)
		,.is_sw_o(is_sw)
		,.is_swtch_o(is_swtch)
		,.has_lab_or_imm_o(has_lab_or_imm)
		,.uses_label_o(uses_label)
		,.is_swtch_or_jr_o(is_swtch_or_jr)
		,.is_staj_or_ldrsw_o(is_staj_or_ldrsw)
		,.is_staj_o(is_staj)
		,.is_in_o(is_in)
		,.read_write_req_o(read_write_req)
		,.write_en_o(write_en)
		,.is_gic_o(is_gic)
		,.dequeue_o(dequeue_o)
		,.restart_o(restart_o)
		,.in_ack_i(in_ack_i)
		,.out_ack_i(out_ack_i)
		,.in_req_o(in_req_o)
		,.out_req_o(out_req_o)
		,.instr_count_o(instr_count)
	);
	
	datapath datapath_module
	(
		.clk(clk)
		,.reset_i(reset_i)
      ,.is_jal_i(is_jal)
		,.is_dmem_i(is_dmem)
		,.is_alu_i(is_alu)
		,.op_code_i(op_code)
		,.wa_i(wa)
		,.ra0_i(ra0)
		,.ra1_i(ra1)
		,.wen_i(wen)
		,.ldinst_valid_i(ldinst_valid)
		,.is_computation_imm_i(is_computation_imm)
		,.is_sw_i(is_sw)
		,.is_staj_or_ldrsw_i(is_staj_or_ldrsw)
		,.is_staj_i(is_staj)
		,.is_swtch_i(is_swtch)
		,.has_lab_or_imm_i(has_lab_or_imm)
		,.uses_label_i(uses_label)
		,.is_swtch_or_jr_i(is_swtch_or_jr)
		,.is_in_i(is_in)
		,.is_gic_i(is_gic)
		,.read_write_req_i(read_write_req)
		,.write_en_i(write_en)
		,.instruction_valid_i(instruction_valid_i)
		,.instruction_addr_i(instruction_addr_i)
		,.instruction_label_i(instruction_label_i)
		,.instruction_imm_i(instruction_imm_i)
		,.instr_count_i(instr_count)
		,.restart_addr_o(restart_addr_o)
		,.refused_o(refused)
		,.branch_o(branch)
		,.in_data_i(in_data_i)
		,.out_data_o(out_data_o)
		,.in_addr_o(in_addr_o)
		,.out_addr_o(out_addr_o)
		,.rd0_o(rd0_o)
		,.rd1_o(rd1_o)
		,.wd_o(wd_o)
	);	
	
 endmodule
 
